package org.jeecg.modules.exTender.controller;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.checkerframework.checker.units.qual.A;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.system.base.controller.JeecgController;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.FileUtil;
import org.jeecg.common.util.RecursiveFileDeleter;
import org.jeecg.common.util.sm.utils.SM4Encryption;
import org.jeecg.modules.exOperationRecord.entity.ExOperationRecord;
import org.jeecg.modules.exOperationRecord.service.IExOperationRecordService;
import org.jeecg.modules.exProject.entity.ExSection;
import org.jeecg.modules.exProject.service.IExSectionService;
import org.jeecg.modules.exTender.entity.ExTenderList;
import org.jeecg.modules.exTender.entity.ExTenderListVariable;
import org.jeecg.modules.exTender.service.IExTenderListService;
import org.jeecg.modules.exTender.service.IExTenderListVariableService;
import org.jeecg.modules.exTender.vo.ExSectionBidRecord;
import org.jeecg.modules.exTender.vo.ExTenderFileVo;
import org.jeecg.modules.message.handle.enums.ZbFileVariableTypeEnum;
import org.jeecg.modules.system.entity.SysUser;
import org.jeecg.modules.system.service.ISysUserService;
import org.simpleframework.xml.core.Validate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.File;
import java.math.BigDecimal;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description: 投标人管理
 * @Author: jeecg-boot
 * @Date: 2024-11-09
 * @Version: V1.0
 */
@Api(tags = "投标人管理")
@RestController
@RequestMapping("/exTender/exTenderList")
@Slf4j
public class ExTenderListController extends JeecgController<ExTenderList, IExTenderListService> {
    @Autowired
    private IExTenderListService exTenderListService;
    @Autowired
    private IExSectionService exSectionService;
    @Autowired
    private IExTenderListVariableService variableService;
    @Autowired
    private IExTenderListService tenderListService;
    @Autowired
    private ISysUserService userService;
    @Value(value = "${jeecg.path.upload}")
    private String uploadpath;

    /**
     * 分页列表查询
     *
     * @param exTenderList
     * @param pageNo
     * @param pageSize
     * @param req
     * @return
     */
    //@AutoLog(value = "投标人管理-分页列表查询")
    @ApiOperation(value = "投标人管理-分页列表查询", notes = "投标人管理-分页列表查询")
    @GetMapping(value = "/list")
    public Result<IPage<ExTenderList>> queryPageList(ExTenderList exTenderList,
                                                     @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                                                     @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
                                                     HttpServletRequest req) {
        QueryWrapper<ExTenderList> queryWrapper = QueryGenerator.initQueryWrapper(exTenderList, req.getParameterMap());
        Page<ExTenderList> page = new Page<ExTenderList>(pageNo, pageSize);
        IPage<ExTenderList> pageList = exTenderListService.page(page, queryWrapper);
        return Result.OK(pageList);
    }


    /**
     * 分页列表查询
     *
     * @param bidSectionId
     * @return
     */
    //@AutoLog(value = "投标人管理-分页列表查询")
    @ApiOperation(value = "投标人管理-根据标段ID查询", notes = "投标人管理-根据标段ID查询")
    @GetMapping(value = "/listByBidSectionId")
    public Result<List<ExTenderList>> queryByBidSectionId(String bidSectionId, @RequestParam(required = false) String realBusinessId) {
        LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        List<ExTenderList> tenderList = exTenderListService.queryBySectionIdAndExpertId(bidSectionId, realBusinessId, sysUser.getId());
        return Result.OK(tenderList);
    }

    /**
     * 添加
     *
     * @param exTenderList
     * @return
     */
    @AutoLog(value = "投标人管理-添加")
    @ApiOperation(value = "投标人管理-添加", notes = "投标人管理-添加")
    //@RequiresPermissions("org.jeecg.modules:ex_tender_list:add")
    @PostMapping(value = "/add")
    @Transactional(rollbackFor = JeecgBootException.class)
    public Result<String> add(@RequestBody ExTenderList exTenderList) {
        exTenderListService.saveInfo(exTenderList);
        return Result.OK("添加成功！");
    }

    /**
     * 编辑
     *
     * @param exTenderList
     * @return
     */
    @AutoLog(value = "投标人管理-编辑")
    @ApiOperation(value = "投标人管理-编辑", notes = "投标人管理-编辑")
    //@RequiresPermissions("org.jeecg.modules:ex_tender_list:edit")
    @RequestMapping(value = "/edit", method = {RequestMethod.PUT, RequestMethod.POST})
    public Result<String> edit(@RequestBody ExTenderList exTenderList) {
        exTenderListService.updateById(exTenderList);
        return Result.OK("编辑成功!");
    }

    /**
     * 通过id删除
     *
     * @param id
     * @return
     */
    @AutoLog(value = "投标人管理-通过id删除")
    @ApiOperation(value = "投标人管理-通过id删除", notes = "投标人管理-通过id删除")
    //@RequiresPermissions("org.jeecg.modules:ex_tender_list:delete")
    @DeleteMapping(value = "/delete")
    public Result<String> delete(@RequestParam(name = "id", required = true) String id) {
        exTenderListService.removeById(id);
        return Result.OK("删除成功!");
    }

    /**
     * 批量删除
     *
     * @param ids
     * @return
     */
    @AutoLog(value = "投标人管理-批量删除")
    @ApiOperation(value = "投标人管理-批量删除", notes = "投标人管理-批量删除")
    //@RequiresPermissions("org.jeecg.modules:ex_tender_list:deleteBatch")
    @DeleteMapping(value = "/deleteBatch")
    public Result<String> deleteBatch(@RequestParam(name = "ids", required = true) String ids) {
        this.exTenderListService.removeByIds(Arrays.asList(ids.split(",")));
        return Result.OK("批量删除成功!");
    }

    /**
     * 通过id查询
     *
     * @param id
     * @return
     */
    //@AutoLog(value = "投标人管理-通过id查询")
    @ApiOperation(value = "投标人管理-通过id查询", notes = "投标人管理-通过id查询")
    @GetMapping(value = "/queryById")
    public Result<ExTenderList> queryById(@RequestParam(name = "id", required = true) String id) {
        ExTenderList exTenderList = exTenderListService.getById(id);
        if (exTenderList == null) {
            return Result.error("未找到对应数据");
        }
        return Result.OK(exTenderList);
    }

    /**
     * 导出excel
     *
     * @param request
     * @param exTenderList
     */
    //@RequiresPermissions("org.jeecg.modules:ex_tender_list:exportXls")
    @RequestMapping(value = "/exportXls")
    public ModelAndView exportXls(HttpServletRequest request, ExTenderList exTenderList) {
        return super.exportXls(request, exTenderList, ExTenderList.class, "投标人管理");
    }

    /**
     * 通过excel导入数据
     *
     * @param request
     * @param response
     * @return
     */
    //@RequiresPermissions("ex_tender_list:importExcel")
    @RequestMapping(value = "/importExcel", method = RequestMethod.POST)
    public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
        return super.importExcel(request, response, ExTenderList.class);
    }

    @ApiOperation(value = "标段（包）主表ID查询", notes = "标段（包）-通主表ID查询")
    @GetMapping(value = "/queryExSectionByMainId")
    public Result<List<ExSectionBidRecord>> queryExSectionListByMainId(@RequestParam(name = "projectId", required = true) String projectId) {
        List<ExSectionBidRecord> exSectionBidRecordList = new ArrayList<>();
        LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        LambdaQueryWrapper<ExTenderList> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ExTenderList::getBidderUserId, sysUser.getId());
        queryWrapper.eq(ExTenderList::getProjectId, projectId);
        List<ExTenderList> tenderLists = exTenderListService.list(queryWrapper);
        List<String> sectionIdList = tenderLists.stream().map(ExTenderList::getBidSectionId).collect(Collectors.toList());

        List<ExSection> exSectionList = exSectionService.selectByMainId(projectId);
        for (int i = 0; i < exSectionList.size(); i++) {
            ExSection exSection = exSectionList.get(i);
            ExSectionBidRecord exSectionBidRecord = new ExSectionBidRecord();
            BeanUtils.copyProperties(exSection, exSectionBidRecord);
            exSectionBidRecord.setUploadCompleted(false);
            if(sectionIdList.contains(exSection.getId())){
                exSectionBidRecord.setUploadCompleted(true);
                Optional<ExTenderList> tenderListOptional = tenderLists.stream().filter(item -> item.getBidSectionId().equals(exSection.getId())).findFirst();
                if(tenderListOptional.isPresent()){
                    exSectionBidRecord.setExTenderList(tenderListOptional.get());
                }
            }
            exSectionBidRecordList.add(exSectionBidRecord);
        }

        return Result.OK(exSectionBidRecordList);
    }

    /*****投标文件解密*****/
    // 1.复制并修改.file文件为.zip
    // 2.解压.zip
    // 3.解密.enc文件
    // 4、读取project.json,设置投标文件路径（.pdf）
    @ApiOperation(value = "投标文件-解密", notes = "解密")
    @PostMapping(value = "/desTenderFile")
    public Result<String> desTenderFile(@RequestBody @Valid ExTenderFileVo fileVo) throws Exception {
        LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        SysUser user = userService.getUserByName(sysUser.getUsername());
        if(user.getIsCa().intValue() == 0){
            return Result.error("解密失败，用户未绑定CA");
        }
        if(StringUtils.isEmpty(user.getCasCode())){
            return Result.error("解密失败，未获取到CA信息");
        }

        ExTenderList exTenderList = exTenderListService.getById(fileVo.getTenderListId());
        if (exTenderList == null) {
            return Result.error("未找到投标信息");
        }
        if(StringUtils.isEmpty(exTenderList.getAttachment())){
            return Result.error("尚未上传投标文件");
        }
        String filePath = uploadpath + File.separator +exTenderList.getAttachment();
        File file = new File(filePath );
        if(!file.exists()){
            return Result.error("投标文件不存在");
        }
        // 先删除变量
        variableService.remove(new LambdaQueryWrapper<ExTenderListVariable>().eq(ExTenderListVariable :: getExTenderListId , exTenderList.getId()));

        // 1.复制文件.zip
        String zipFilePath = uploadpath + File.separator +exTenderList.getAttachment().replace(".file",".zip");
        FileUtil.copyFile(filePath,zipFilePath);

        // 2 zip文件解压
        String zipDir = zipFilePath.replace(".zip","")+File.separator;
        FileUtil.uncompress(zipFilePath,zipDir);

        // 3 遍历解密.enc
        File folder = new File(zipDir);
        if (!folder.exists() || !folder.isDirectory()) {
            return Result.error("投标文件解压失败");
        }
        File[] files = folder.listFiles();
        if (files == null) {
            // 删除已解文件
            RecursiveFileDeleter.deleteRecursively(Paths.get(zipDir));
            return Result.error("投标文件enc为空");
        }
        for (File encFile : files) {
            String desFile = zipDir + encFile.getName().replace(".enc","");
            try{
                SM4Encryption.decryptFile(encFile.getPath(),desFile,user.getCasCode().getBytes());
            }catch (Exception e){
                e.printStackTrace();
                // 删除已解文件
                RecursiveFileDeleter.deleteRecursively(Paths.get(zipDir));
                return Result.error("解密失败，请联系管理员");

            }
        }

        // 4、读取project.json,设置投标文件路径（.pdf）
        File[] newFiles = folder.listFiles();
        StringBuffer sb = new StringBuffer();
//        boolean desCert = false;
//        // 先遍历一遍，解密数字信封
//        for (File desFile : newFiles) {
//            String defileName  = desFile.getName();
//            if(defileName.endsWith("cert.key")){
//                String cert = FileUtils.readFileToString(desFile,"UTF-8");
//                if(cert.equals(fileVo.getCertKey())){
//                    desCert = true;
//                }
//            }
//        }
//
//        if(!desCert){
//            // 删除已解文件
//            RecursiveFileDeleter.deleteRecursively(Paths.get(zipDir));
//            return Result.error("解密失败，请更换正确的CA解密");
//        }
        for (File desFile : newFiles) {
            String defileName  = desFile.getName();
            // 设置解密后的pdf投标文件
            if(defileName.endsWith(".pdf")){
                exTenderList.setPdfUrl(exTenderList.getAttachment().replace(".file","") + File.separator + defileName);
            }
            // 暂时定义投标文件为project.json 非该文件咱不支持后续加解密后再调整
            if(desFile.getName().equals("project.json")){
                String jsonContent = FileUtils.readFileToString(desFile,"UTF-8");
                JSONObject jsonObject = JSONObject.parseObject(jsonContent);
                JSONArray jsonArray = jsonObject.getJSONArray("variable");
                jsonArray.stream().forEach(jsonObejct->{
                    // 变量入库
                    JSONObject obj = (JSONObject)jsonObejct;
                    // 报价
                    if(ZbFileVariableTypeEnum.BJ.getType().toString().equals(obj.get("columnType").toString())){
                        exTenderList.setBidPrice(new BigDecimal(obj.get("columnName").toString()));
                        exTenderList.setPriceCurrency("156"); // 币种 156人民币
                        exTenderList.setPriceUnit("0"); // 0元 1万
                    }else if(ZbFileVariableTypeEnum.GQ.getType().toString().equals(obj.get("columnType").toString())){
                        exTenderList.setTimeLimit(Integer.parseInt(obj.get("columnName").toString()));
                    }else{
                        // 动态变量
                        ExTenderListVariable variable =new ExTenderListVariable();
                        variable.setExTenderListId(exTenderList.getId());
                        variable.setSetValue(obj.get("columnName")==null?null:obj.get("columnName").toString());
                        variable.setExTenderFileSetVariableId(obj.get("columnName").toString());
                        variableService.save(variable);
                    }
                    sb.append("变量名："+obj.get("columnKey").toString() + ",变量值："+obj.get("columnName").toString() + ";");
                });
            }
        }
        exTenderList.setDecryptStatus(1);//设置已解密
        // 解密变量将工期 报价 写入投标人记录表
        exTenderListService.updateById(exTenderList);
        return Result.OK(sb.toString());
    }

    private static StringBuffer arrayIdToString(JSONObject jsonobejct,
                                                StringBuffer sBuffer) {
        return sBuffer.append(jsonobejct.getInteger("id")).append(",");
    }


}
